package common

import (
	"context"
	"encoding/json"
	"fmt"
	"github.com/matishsiao/goInfo"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
	"path/filepath"

	restclient "k8s.io/client-go/rest"
	"math/rand"
	"net"
	"os"
	"strings"
	"time"
)

// 给一个超时秒数 返回一个 带超时时间的ctx 和 CancelFunc
func GenTimeoutContext(tw int) (context.Context, context.CancelFunc) {
	return context.WithTimeout(context.Background(), time.Duration(tw)*time.Second)
}

func GenK8sClientSetByKubeConfigContent(c string) (*restclient.Config, *kubernetes.Clientset, error) {
	//if basePath == "" {
	//	basePath = "D:/nyy_work/go_path/src/bigdevops"
	//}
	basePath := "./"
	tmpKubeConfigFile, err := os.CreateTemp(basePath, "tmp-kubeconfig-")

	if err != nil {
		return nil, nil, err
	}

	pwd, _ := os.Getwd()

	//defer tmpKubeConfigFile.Close()
	fName := filepath.Join(pwd, tmpKubeConfigFile.Name())
	//fmt.Println("tmpKubeConfigFile.Name()", tmpKubeConfigFile.Name())
	defer func() {
		tmpKubeConfigFile.Close()
		err := os.Remove(fName)
		if err != nil {
			fmt.Printf("GenK8sClientSetByKubeConfigContent删除文件错误：%v \n", err)
		}

	}()
	_, err = tmpKubeConfigFile.WriteString(c)
	if err != nil {
		return nil, nil, err
	}

	// 先解析kubeconfig 拿到 apiserver
	kConfig, err := clientcmd.BuildConfigFromFlags("", tmpKubeConfigFile.Name())
	if err != nil {
		return nil, nil, err
	}

	// create the clientset
	clientset, err := kubernetes.NewForConfig(kConfig)
	if err != nil {
		return nil, nil, err
	}
	return kConfig, clientset, nil
}

// 返回jsonstr

func GenJsonString(str string) string {

	data, _ := json.Marshal(str)
	return string(data)

}

func TimeNowString() string {
	return TimeFormat(time.Now())
}

func TimeFormat(t time.Time) string {
	return t.Format("2006-01-02 15:04:05")
}

// 返回几天前的日期
func GetDayAgoDate(num int) string {
	return time.Now().Add(time.Duration(num) * time.Hour * 24).Format("2006-01-02")
}

func GenStringArrayByChangeLine(text string) []string {
	res := []string{}

	lines := strings.Split(text, "\n")
	for _, line := range lines {
		line = strings.TrimSpace(line)
		res = append(res, line)
	}

	return res
}

func GenStringArrayByMap(m map[string]string) []string {
	res := []string{}
	for k, v := range m {
		res = append(res, fmt.Sprintf("%s=%s", k, v))
	}
	return res
}

func GenKvStringByMap(m map[string]string) string {
	res := ""
	for k, v := range m {
		res = fmt.Sprintf("%s %s=%s", res, k, v)
	}
	return res
}

func GenMapByKvStrings(kvs []string) map[string]string {
	m := map[string]string{}
	for _, kv := range kvs {
		res := strings.Split(kv, "=")
		if len(res) != 2 {
			continue
		}
		m[res[0]] = res[1]
	}
	return m
}

func GenFormKvFromStringArray(kvs []string) []FromKvOneItem {
	arr := make([]FromKvOneItem, 0)
	for _, kv := range kvs {
		res := strings.Split(kv, "=")
		if len(res) != 2 {
			continue
		}
		k, v := res[0], res[1]

		arr = append(arr, FromKvOneItem{
			Key:   k,
			Value: v,
		})
	}
	return arr
}
func GenStringArrayByFormKv(items []FromKvOneItem) (arr []string) {

	for _, item := range items {
		if item.Key == "" {
			continue
		}

		res := fmt.Sprintf("%s=%s", item.Key, item.Value)

		arr = append(arr, res)
	}
	return arr
}

func GenFormKvFromStringArrayOnlyKey(kvs []string) []FromKvOneItem {
	arr := make([]FromKvOneItem, 0)
	for _, key := range kvs {
		if key == "" {
			continue
		}
		arr = append(arr, FromKvOneItem{
			Key: key,
		})
	}
	return arr
}

func GenStringArrayByFormKvOnlyKey(items []FromKvOneItem) (arr []string) {
	for _, item := range items {
		arr = append(arr, item.Key)
	}
	return arr
}

// 通过构造 网络连接 通过路由走到真正的出口 ，就能拿到真正的ip地址
func GetLocalIp() string {
	conn, err := net.Dial("udp", "8.8.8.8:53")
	if err != nil {
		fmt.Printf("get local addr err:%v\n", err)
		return ""
	} else {
		localIp := strings.Split(conn.LocalAddr().String(), ":")[0]
		conn.Close()
		return localIp
	}
}

// 返回主机名的
func GetHostName() string {

	nodeName := os.Getenv("MY_NODE_NAME")
	if nodeName == "" {
		nodeName, _ = os.Hostname()
	}
	return nodeName
}

func GetNodeInfo() SysInfo {
	var si SysInfo

	si.GetSysInfo()
	gi, _ := goInfo.GetInfo()
	si.OsType = gi.Kernel
	return si
}

func WriteFileWithString(filePath, content string) error {
	return os.WriteFile(filePath, []byte(content), 0644)
}

func ReadFile(path string) (string, error) {
	res, err := os.ReadFile(path)
	return string(res), err
}

func Frn(n int) int {
	rand.Seed(time.Now().UnixNano())
	return rand.Intn(n)
}
